/**
 * 
 */
package de.cbf.cam.dsa.model.entities;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

import de.cbf.cam.dsa.model.entities.maneuvers.ManeuverDesc;
import de.cbf.cam.dsa.model.entities.weapon.OneWeapon;
import de.cbf.cam.dsa.model.entities.weapon.valueModifier.WeaponValueModifier;
import de.cbf.cam.dsa.model.persistence.Header;
import de.cbf.cam.dsa.model.prerequisites.Prereq;

/**
 * @author Nebelritter
 *
 */
@Entity
public class WeaponStyle extends Header{
	/**
	 * @uml.property  name="talentName"
	 */
	private String talentName;
	
	/**
	 * @uml.property  name="name"
	 */
	private String name;
	
	/**
	 * @uml.property  name="prereqs"
	 * @uml.associationEnd  multiplicity="(0 -1)" elementType="de.cbf.cam.dsa.model.prerequisites.Prereq"
	 */
	private List<Prereq> prereqs= new ArrayList<Prereq>();
	
	/**
	 * @uml.property  name="weaponValueModifiers"
	 * @uml.associationEnd  multiplicity="(0 -1)" elementType="de.cbf.cam.dsa.model.entities.weapon.valueModifier.WeaponValueModifier"
	 */
	private List<WeaponValueModifier> weaponValueModifiers = new ArrayList<WeaponValueModifier>();
	/**
	 * from style and weaponMain itself
	 * @uml.property  name="possibleManouvers"
	 * @uml.associationEnd  qualifier="getManeuverName:java.lang.String de.cbf.cam.dsa.model.entities.maneuvers.ManeuverDesc"
	 */
	private HashMap<String,ManeuverDesc> possibleManouvers = new HashMap<String,ManeuverDesc>();
	/**
	 * 
	 */
	public WeaponStyle(String talentName) {
		super();
		this.talentName = talentName;
	}

	public boolean testCharacterForStyleAvailble(OneNPC character){
		boolean result = true;
		for(int i =0;i<prereqs.size();i++){
			result = result&&prereqs.get(i).characterMeetsPrereq(character);
		}
		return result;
	}
	
	public void modifyWeapon(OneWeapon weapon){		
		for(int i =0;i<weaponValueModifiers.size();i++){
			weapon.addValueModifier(weaponValueModifiers.get(i));
		}
	}
	
	@Override
	@Id
	public String getGuid() {		
		return guid;
	}

	@Override
	public void setGuid(String guid) {
		this.guid = guid;		
	}	
	public String getName() {
		if(name == null){
			return talentName;
		}
		return name;
	}

	/**
	 * @param name
	 * @uml.property  name="name"
	 */
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * @return
	 * @uml.property  name="talentName"
	 */
	public String getTalentName() {
		return talentName;
	}
	/**
	 * @param talentName
	 * @uml.property  name="talentName"
	 */
	public void setTalentName(String talentName) {
		this.talentName = talentName;
	}
	
	@ManyToMany(cascade=CascadeType.ALL)
	public List<Prereq> getPrerequisites() {	
		return prereqs;
	}	
	public void setPrerequisites(List<Prereq> prereqs) {
		this.prereqs = prereqs;
	}
	public boolean addPrerequisite(Prereq prereq){
		return prereqs.add(prereq);
	}
	public boolean removePrerequisite(Prereq prereq){
		return prereqs.remove(prereq);
	}
	
	@ManyToMany(cascade=CascadeType.ALL)
	public List<WeaponValueModifier> getWeaponValueModifiers() {
		return weaponValueModifiers;
	}	
	public void setWeaponValueModifiers(
			List<WeaponValueModifier> weaponValueModifiers) {
		this.weaponValueModifiers = weaponValueModifiers;
	}
	public boolean addWeaponValueModifer(WeaponValueModifier modifier){
		return weaponValueModifiers.add(modifier);
	}
	public boolean removeWeaponValueModifer(WeaponValueModifier modifier){
		return weaponValueModifiers.remove(modifier);
	}
		
	@ManyToMany(cascade=CascadeType.ALL)
	public List<ManeuverDesc> getPossibleManeuvers() {
		List<ManeuverDesc> resultList = new ArrayList<ManeuverDesc>();
		resultList.addAll(possibleManouvers.values());
		return  resultList;
	}
	
	public void setPossibleManeuvers(List<ManeuverDesc> possibleManeuvers) {
		for(int i = 0;i<possibleManeuvers.size();i++){
			ManeuverDesc description = possibleManeuvers.get(i);
			this.possibleManouvers.put(description.getManeuverName(),description);
		}		 
	}
	
	public boolean addManeuver(ManeuverDesc maneuver){
		ManeuverDesc desc = possibleManouvers.put(maneuver.getManeuverName(), maneuver);
		if(desc == null){
			return true;
		}else{
			return false;
		}		
	}
	
	public ManeuverDesc getManeuver(String maneuverName){
		return possibleManouvers.get(maneuverName);
	}
	
	public boolean removeManeuver(ManeuverDesc maneuver){
		ManeuverDesc desc = possibleManouvers.remove(maneuver.getManeuverName());
		if(desc == null){
			return true;
		}else{
			return false;
		}	
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime
				* result
				+ ((possibleManouvers == null) ? 0 : possibleManouvers
						.hashCode());
		result = prime * result
				+ ((prereqs == null) ? 0 : prereqs.hashCode());
		result = prime * result
				+ ((talentName == null) ? 0 : talentName.hashCode());
		result = prime
				* result
				+ ((weaponValueModifiers == null) ? 0 : weaponValueModifiers
						.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		WeaponStyle other = (WeaponStyle) obj;
		if (possibleManouvers == null) {
			if (other.possibleManouvers != null)
				return false;
		} else if (!possibleManouvers.equals(other.possibleManouvers))
			return false;
		if (prereqs == null) {
			if (other.prereqs != null)
				return false;
		} else if (!prereqs.equals(other.prereqs))
			return false;
		if (talentName == null) {
			if (other.talentName != null)
				return false;
		} else if (!talentName.equals(other.talentName))
			return false;
		if (weaponValueModifiers == null) {
			if (other.weaponValueModifiers != null)
				return false;
		} else if (!weaponValueModifiers.equals(other.weaponValueModifiers))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return talentName;
	}

	

	
}
